package co.yixiang.modules.user.service.mapper;

import co.yixiang.common.mapper.CoreMapper;
import co.yixiang.modules.user.domain.YxUser;
import co.yixiang.modules.user.service.dto.PromUserDto;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.List;

/**
 * 用户模块的Mapper接口，继承自CoreMapper，用于处理用户相关的数据操作
 */
@Repository
public interface UserMapper extends CoreMapper<YxUser> {

    /**
     * 获取用户推广列表
     *
     * @param page 分页对象，用于分页查询
     * @param uids 用户ID列表，用于查询指定用户的信息
     * @param keyword 关键字，用于模糊查询用户的昵称或手机号
     * @param orderBy 排序字符串，用于指定查询结果的排序方式
     * @return 返回一个PromUserDto对象的列表，包含用户相关信息
     */
    @Select("<script>SELECT u.uid,u.nickname,u.avatar,DATE_FORMAT(u.create_time,'%Y/%m/%d') as time," +
            "u.spread_count as childCount,COUNT(o.id) as orderCount," +
            "IFNULL(SUM(o.pay_price),0) as numberCount FROM yx_user u " +
            "LEFT JOIN yx_store_order o ON u.uid=o.uid " +
            "WHERE u.uid in <foreach item='id' index='index' collection='uids' " +
            " open='(' separator=',' close=')'>" +
            "   #{id}" +
            " </foreach> <if test='keyword != null'>" +
            " AND ( u.nickname LIKE CONCAT(CONCAT('%',#{keyword}),'%') OR u.phone LIKE CONCAT(CONCAT('%',#{keyword}),'%'))</if>" +
            " GROUP BY u.uid ORDER BY ${orderByStr} " +
            "</script>")
    List<PromUserDto> getUserSpreadCountList(Page page,
                                             @Param("uids") List uids,
                                             @Param("keyword") String keyword,
                                             @Param("orderByStr") String orderBy);

    /**
     * 减少用户余额
     *
     * @param payPrice 支付金额，用于减少用户余额
     * @param uid 用户ID，指定要操作的用户
     * @return 返回受影响的行数，表示更新操作是否成功
     */
    @Update("update yx_user set now_money=now_money-#{payPrice}" +
            " where uid=#{uid}")
    int decPrice(@Param("payPrice") BigDecimal payPrice, @Param("uid") Long uid);

    /**
     * 增加用户支付次数
     *
     * @param uid 用户ID，指定要操作的用户
     * @return 返回受影响的行数，表示更新操作是否成功
     */
    @Update("update yx_user set pay_count=pay_count+1" +
            " where uid=#{uid}")
    int incPayCount(@Param("uid") Long uid);

    /**
     * 增加用户余额
     *
     * @param uid 用户ID，指定要操作的用户
     * @param price 金额，用于增加用户余额
     * @return 返回受影响的行数，表示更新操作是否成功
     */
    @Update("update yx_user set now_money=now_money+#{price}" +
            " where uid=#{uid}")
    int incMoney(@Param("uid") Long uid, BigDecimal price);

    /**
     * 减少用户积分
     *
     * @param integral 积分数，用于减少用户的积分
     * @param uid 用户ID，指定要操作的用户
     * @return 返回受影响的行数，表示更新操作是否成功
     */
    @Update("update yx_user set integral=integral-#{integral}" +
            " where uid=#{uid}")
    int decIntegral(@Param("integral") double integral, @Param("uid") Long uid);

    /**
     * 增加用户积分
     *
     * @param integral 积分数，用于增加用户的积分
     * @param uid 用户ID，指定要操作的用户
     * @return 返回受影响的行数，表示更新操作是否成功
     */
    @Update("update yx_user set integral=integral+#{integral}" +
            " where uid=#{uid}")
    int incIntegral(@Param("integral") double integral, @Param("uid") Long uid);

    /**
     * 更新用户状态
     *
     * @param status 用户状态，用于更新用户的状态
     * @param id 用户ID，指定要操作的用户
     */
    @Update("update yx_user set status = #{status} where uid = #{id}")
    void updateOnstatus(@Param("status") Integer status, @Param("id") Long id);

    /**
     * 更新用户余额
     *
     * @param money 金额，用于更新用户的余额
     * @param id 用户ID，指定要操作的用户
     */
    @Update("update yx_user set now_money = now_money + ${money} where uid = #{id}")
    void updateMoney(@Param("money") double money, @Param("id") long id);

    /**
     * 增加用户佣金
     *
     * @param price 佣金金额，用于增加用户的佣金
     * @param id 用户ID，指定要操作的用户
     */
    @Update("update yx_user set brokerage_price = brokerage_price+ ${price} where uid = #{id}")
    void incBrokeragePrice(@Param("price") BigDecimal price, @Param("id") Long id);

}
